package com.xc.hotelmgr.datapusherali.service.fz.impl;

import com.google.common.collect.Lists;
import com.xc.hotelmgr.datapusherali.pojo.ali.ZqDate;
import com.xc.hotelmgr.datapusherali.pojo.mq.HotelCallBack;
import com.xc.hotelmgr.datapusherali.pojo.mq.RatesCallBack;
import com.xc.hotelmgr.datapusherali.pojo.mybatis.*;
import com.xc.hotelmgr.datapusherali.service.fz.HotelService;
import com.xc.hotelmgr.datapusherali.service.fz.RatesService;
import com.xc.hotelmgr.datapusherali.service.mybatis.*;
import com.xc.hotelmgr.datapusherali.utils.DateUtils;
import com.xc.hotelmgr.datapusherali.utils.FZUtil;
import com.xc.hotelmgr.datapusherali.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class HotelServiceImpl implements HotelService {

    @Autowired
    private HtHotelinfoService htHotelinfoService;

    @Autowired
    private HtPhysicalRoomService htPhysicalRoomService;

    @Autowired
    private HtLogicRoomService htLogicRoomService;

    @Autowired
    private DtUpHtlService dtUpHtlService;

    @Autowired
    private OpCommPriceService opCommPriceService;

    @Autowired
    private OpHtlPriceService opHtlPriceService;

    @Autowired
    private OpHtlGroupService opHtlGroupService;

    @Autowired
    private OpTaskDetailService opTaskDetailService;

    @Autowired
    private OpOurRateplanService opOurRateplanService;

    @Autowired
    private RatesService ratesService;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 全量酒店推送（包括 酒店 房型 价格政策 价格）
     *
     * @param storeId
     * @param upHtlId
     */
    @Override
    public void AllSend(int storeId, Long upHtlId, Long taskId, String appKey, String secret, String sessionKey) {
        ZqDate zqDate = redisUtils.get(appKey, ZqDate.class);
        // 数据库关联查询
        HtHotelinfo htHotelinfo = htHotelinfoService.selectAll(upHtlId);
        // 数据库关联查询价格政策
        if (htHotelinfo != null) {
            List<HtPhysicalRoom> htPhysicalRooms = htHotelinfo.getHtPhysicalRooms();
            Long hotelId = htHotelinfo.getId();

            // 获取酒店加价
            List<OpHtlPrice> opHtlPrices = opHtlPriceService.getByStoreIdAndHotelId(storeId, hotelId);
            if (opHtlPrices == null) {
                opHtlPrices = Lists.newArrayList();
            }

            // 查询自定义价格计划及加价配置
            List<OpOurRateplan> opOurRateplans = opOurRateplanService.getRatePlanPrice(storeId, upHtlId);
            if (opOurRateplans == null || opOurRateplans.isEmpty()) {
                return;
            }

            // 获取通用加价
            List<OpCommPrice> opCommPrices = opCommPriceService.getByStoreId(storeId);
            if (opCommPrices == null) {
                opCommPrices = Lists.newArrayList();
            }
            //电话号码不能超过30位
            if (htHotelinfo.getPhone().contains(";")) {
                htHotelinfo.setPhone(htHotelinfo.getPhone().split(";")[0]);
            }
            if (htHotelinfo.getPhone().contains(",")) {
                htHotelinfo.setPhone(htHotelinfo.getPhone().split(",")[0]);
            }
            if(htHotelinfo.getPhone().length()>30){
                htHotelinfo.setPhone(htHotelinfo.getPhone().substring(0,29));
            }
            // 调用飞猪接口推送
            String resultHotel = FZUtil.hotelSend(htHotelinfo, appKey, sessionKey, secret);
            // 酒店推送结果判断
            if (resultHotel.contains("xhotel_add_response")) {
                //用飞猪酒店信息更新本地酒店信息
                htHotelinfoService.hotelUpdateByAli(resultHotel);
                // 遍历物理房型 推送
                for (HtPhysicalRoom room : htPhysicalRooms) {
                    List<HtLogicRoom> htLogicRooms = room.getHtLogicRooms();
                    Long roomCode = room.getRoomCode();   // 房型编码
                    if (StringUtils.isBlank(room.getBedPad())) {
                        room.setBedPad(room.getRoomName());
                    }
                    String roomResult = FZUtil.roomSend(room, appKey, sessionKey, secret);
                    // 房型推送结果判断
                    if (roomResult.contains("xhotel_roomtype_add_response")) {
                        //用飞猪房型信息更新本地房型信息
                        htPhysicalRoomService.roomUpdateByAli(roomResult);

                        // 遍历逻辑房型推送
                        for (HtLogicRoom htLogicRoom : htLogicRooms) {
                            List<HtDailyRoom> htDailyRooms = htLogicRoom.getHtDailyRooms();
                            Long rpCode = htLogicRoom.getRpCode();                  // 默认价格计划编码
                            String cancleJsonStr = htLogicRoom.getCancelPolicy();   // 默认价格政策
                            Integer breakfastNum = htLogicRoom.getBreakfastNum();   // 默认早餐
                            for (OpOurRateplan opOurRateplan : opOurRateplans) {
//                                int id = opOurRateplan.getId(); // 用id是否为0断价格政策是否为自定义
                                String opCancleJsonStr;   // 自定义新价格政策
                                Integer opBreakfastNum;   // 自定义早餐数
                                String opRpCode;            // 自定义价格政策编码

//                                if (id != 0) {                // 有自定义价格政策
                                List<OpOurRateplanPrice> opOurRateplanPrices = opOurRateplan.getOpOurRateplanPrices();//加价配置
                                opRpCode = rpCode + "XC" + opOurRateplan.getId(); // 价格政策新编码    rpCode + "XC" + 自定义价格政策的主键

                                opCancleJsonStr = opOurRateplan.getCancleJsonStr(); // 分组自定义价格政策
                                opBreakfastNum = opOurRateplan.getBreakfastNum();  // 分组自定义早餐数

                                if (!"default".equals(opCancleJsonStr)) {  // 赋值取消政策
                                    cancleJsonStr = opCancleJsonStr;  // 如果自定义退改为不为null或空字串，赋值
                                }

                                if (breakfastNum == 0 & opBreakfastNum != null) { // 如果默认早餐为0，自定义早餐不为空 赋值
                                    breakfastNum = opBreakfastNum;
                                }
//                                } else {
//                                    opRpCode = String.valueOf(rpCode);
//                                }
                                //如果没有配置自定义价格政策加价配置
                                if (opOurRateplanPrices == null) {
                                    opOurRateplanPrices = Lists.newArrayList();
                                }
                                htLogicRoom.setCancelPolicy(cancleJsonStr); // 重新赋值退改政策
                                htLogicRoom.setRateplan_code(opRpCode);    // 重新赋值价格政策编码
                                htLogicRoom.setBreakfastNum(breakfastNum);  // 重新赋值早餐数量
                                htLogicRoom.setChannel(opOurRateplan.getChannel()); //销售渠道
                                // 调用飞猪接口推送
                                String rpResult = FZUtil.logicRoomSend(htLogicRoom, appKey, sessionKey, secret);

                                // 逻辑房型推送结果判断
                                if (rpResult.contains("xhotel_rateplan_add_response")) {
                                    //价格推送
                                    List<HtDailyRoom> htDailyRoomsNew = new ArrayList<>();
                                    for (HtDailyRoom htDailyRoom : htDailyRooms) {
                                        //设置停售日期为0库存
                                        List<String> dateList = Lists.newArrayList();
                                        if (zqDate != null && zqDate.getDateList() != null) {
                                            dateList = zqDate.getDateList();
                                        }
                                        for (String date : dateList) {
                                            if (StringUtils.equals(htDailyRoom.getPriceDate(), date)) {
                                                htDailyRoom.setSaleNum(0);
                                            }
                                        }
                                        int newPrice = FZUtil.calcPrice(opCommPrices, opHtlPrices, opOurRateplanPrices, htDailyRoom); // 价格计算
                                        htDailyRoom.setPrice(newPrice);
                                        htDailyRoomsNew.add(htDailyRoom);
                                    }
                                    String result = FZUtil.ratesSend(htDailyRoomsNew, roomCode, opRpCode, appKey, sessionKey, secret);
                                    if (!result.contains("xhotel_rates_increment_response")) {
                                        OpTaskDetail opTaskDetail = new OpTaskDetail();
                                        opTaskDetail.setTaskId(taskId);
                                        opTaskDetail.setHotelId(upHtlId);
                                        opTaskDetail.setReason(opRpCode + "&" + "价格库存推送失败" + "&" + result);
                                        opTaskDetailService.insertIgnoreNull(opTaskDetail);
                                    }
                                } else {
                                    OpTaskDetail opTaskDetail = new OpTaskDetail();
                                    opTaskDetail.setTaskId(taskId);
                                    opTaskDetail.setHotelId(upHtlId);
                                    opTaskDetail.setReason(opRpCode + "&" + "价格政策推送失败" + "&" + rpResult);
                                    opTaskDetailService.insertIgnoreNull(opTaskDetail);
                                }
                            }
                        }
                    } else {
                        OpTaskDetail opTaskDetail = new OpTaskDetail();
                        opTaskDetail.setTaskId(taskId);
                        opTaskDetail.setHotelId(upHtlId);
                        opTaskDetail.setReason(roomCode + "&" + "房型推送失败" + "&" + roomResult);
                        opTaskDetailService.insertIgnoreNull(opTaskDetail);
                    }
                }
                // 更改分销商酒店的推送状态
                DtUpHtl dtUpHtl = new DtUpHtl();
                dtUpHtl.setStatus(0);
                dtUpHtl.setHotelId(upHtlId);
                dtUpHtl.setStoreId(storeId);
                dtUpHtlService.updateIgnoreNullByHtlIdAndStoreId(dtUpHtl);
            } else {
                OpTaskDetail opTaskDetail = new OpTaskDetail();
                opTaskDetail.setTaskId(taskId);
                opTaskDetail.setHotelId(upHtlId);
                opTaskDetail.setReason("酒店信息推送失败" + "&" + resultHotel);
                opTaskDetailService.insertIgnoreNull(opTaskDetail);
            }
        } else {
            OpTaskDetail opTaskDetail = new OpTaskDetail();
            opTaskDetail.setTaskId(taskId);
            opTaskDetail.setHotelId(upHtlId);
            opTaskDetail.setReason("酒店信息不全(缺少房型或价格政策或价格)");
            opTaskDetailService.insertIgnoreNull(opTaskDetail);
        }
    }

    /**
     * 只推送价态
     *
     * @param storeId
     * @param hotelId
     * @param taskId
     * @param appKey
     * @param secret
     * @param sessionKey
     * @param sendType
     */
    @Override
    public void rpSend(int storeId, Long hotelId, Long taskId, String appKey, String secret, String sessionKey, Integer sendType) throws InterruptedException {
        RatesCallBack ratesCallBack = new RatesCallBack();
        ratesCallBack.setStoreId(storeId);
        ratesCallBack.setAppKey(appKey);
        ratesCallBack.setSecret(secret);
        ratesCallBack.setSessionKey(sessionKey);
        ratesCallBack.setTaskId(taskId);
        Date stDate = new Date();
        List<String> dates = Lists.newArrayList();
        Date enDate = DateUtils.addDateDays(stDate,30);
        while (stDate.before(enDate)){
            dates.add(DateUtils.format(stDate,"yyyy-MM-dd"));
            stDate = DateUtils.addDateDays(stDate,1);
        }
        ratesCallBack.setDates(dates);
        List<HtLogicRoom> logicRooms =  htLogicRoomService.selectRpCodeByHotelCode(hotelId);
        for (HtLogicRoom logicRoom : logicRooms) {
            ratesCallBack.setRpCode(logicRoom.getRpCode());
            // 0:0库存推送  1:店铺正常推送 2:按地区0库存推送 3:按地区推送 4:按分组0库存推送 5:按分组推送
            // 0库存推送，不计算价格
            if (sendType == 0 || sendType == 2 || sendType == 4) {
                ratesService.zeroRatesSend(ratesCallBack);
            } else {
                ratesService.hotelRatesSend(ratesCallBack);
            }
        }
    }

    /**
     * 酒店全量删除（包括 酒店 房型 价格政策 价格）
     *
     * @param store_id
     * @param up_htl_id
     * @return
     */
    @Override
    public void allDelete(int store_id, Long up_htl_id, Long taskId, String appKey, String secret, String sessionKey) {

        // 数据库关联查询
        // 数据库关联查询价格政策
        OpHtlGroup opHtlGroup = opHtlGroupService.getRatePlan(store_id, up_htl_id);
        List<OpOurRateplan> opOurRateplans = new ArrayList<>(); // 自定义价格政策列表
        if (opHtlGroup == null) {
            opOurRateplans.add(new OpOurRateplan());
        } else {
            opOurRateplans = opHtlGroup.getOpOurRateplan();
        }
        HtHotelinfo htHotelinfo = htHotelinfoService.selectAllHotelExceptPs(up_htl_id);
        if (htHotelinfo != null) {
            List<HtPhysicalRoom> htPhysicalRooms = htHotelinfo.getHtPhysicalRooms();
            // 调用飞猪接口删除
            String htlResult = FZUtil.hotelDel(htHotelinfo, appKey, sessionKey, secret);
            if (htlResult.contains("xhotel_delete_response")) {
                for (HtPhysicalRoom htPhysicalRoom : htPhysicalRooms) {
                    List<HtLogicRoom> htLogicRooms = htPhysicalRoom.getHtLogicRooms();
                    for (HtLogicRoom htLogicRoom : htLogicRooms) {
                        Long rpCode = htLogicRoom.getRpCode();
                        for (OpOurRateplan opOurRateplan : opOurRateplans) {
                            int id = opOurRateplan.getId();
                            String newRpCode;
                            if (id != 0) {
                                newRpCode = rpCode + "XC" + opOurRateplan.getId();
                            } else {
                                newRpCode = String.valueOf(rpCode);
                            }
                            htLogicRoom.setRateplan_code(newRpCode);
                            String rpResult = FZUtil.logicRoomDel(htLogicRoom, appKey, sessionKey, secret);
                            if (!rpResult.contains("xhotel_rateplan_delete_response")) {
                                OpTaskDetail opTaskDetail = new OpTaskDetail();
                                opTaskDetail.setTaskId(taskId);
                                opTaskDetail.setHotelId(up_htl_id);
                                opTaskDetail.setReason(rpCode + "&" + "价格政策删除失败" + "&" + rpResult);
                                opTaskDetailService.insertIgnoreNull(opTaskDetail);
                            }
                        }
                    }

                }
                // 更改店铺酒店删除后的状态
                DtUpHtl dtUpHtl = new DtUpHtl();
                dtUpHtl.setStatus(-1);
                dtUpHtl.setHotelId(up_htl_id);
                dtUpHtl.setStoreId(store_id);
                dtUpHtlService.updateIgnoreNullByHtlIdAndStoreId(dtUpHtl);
            } else {
                OpTaskDetail opTaskDetail = new OpTaskDetail();
                opTaskDetail.setTaskId(taskId);
                opTaskDetail.setHotelId(up_htl_id);
                opTaskDetail.setReason("酒店删除失败" + "&" + htlResult);
                opTaskDetailService.insertIgnoreNull(opTaskDetail);
            }
        }
    }

    /**
     * 酒店上下架
     *
     * @param store_id
     * @param up_htl_id
     * @param status
     */
    @Override
    public void hotelUpDown(int store_id, Long up_htl_id, int status, Long taskId, String appKey, String secret, String sessionKey) {

        DtUpHtl dtUpHtl = dtUpHtlService.getByStoreIdAndHotelId(store_id, up_htl_id);
        if (dtUpHtl != null) {
            int state = dtUpHtl.getStatus();
            if (state != -1) { // 酒店删除状态不需要上下架
                // 根据店铺对应的酒店主键id查询出酒店相关信息
                HtHotelinfo htHotelinfo = htHotelinfoService.selectById(up_htl_id);
                // 赋值酒店状态
                String resultPush = FZUtil.hotelStatus(htHotelinfo, appKey, sessionKey, secret, status);

                if (resultPush.contains("xhotel_update_response")) {
                    DtUpHtl dtUpHtl1 = new DtUpHtl();
                    dtUpHtl1.setHotelId(up_htl_id);
                    dtUpHtl1.setStoreId(store_id);
                    dtUpHtl1.setStatus(status);
                    // 更新分销商酒店状态
                    dtUpHtlService.updateIgnoreNullByHtlIdAndStoreId(dtUpHtl1);
                } else {
                    OpTaskDetail opTaskDetail = new OpTaskDetail();
                    opTaskDetail.setTaskId(taskId);
                    opTaskDetail.setHotelId(up_htl_id);
                    opTaskDetail.setReason("酒店状态更改失败（上下架删除）" + "&" + resultPush);
                    opTaskDetailService.insertIgnoreNull(opTaskDetail);
                }
            }
        }
    }

    /**
     * 酒店信息监控更新
     *
     * @param hotelCallBack
     */
    @Override
    public void callBackHotel(HotelCallBack hotelCallBack) {
        Long hotelId = hotelCallBack.getHotelId();
        int storeId = hotelCallBack.getStoreId();
        DtUpHtl dtUpHtl = dtUpHtlService.getByStoreIdAndHotelId(storeId, hotelId);
        // 判断酒店是否在分销商店铺
        if(dtUpHtl!=null) {
            HtHotelinfo htHotelinfo = htHotelinfoService.selectById(hotelId);
            String sessionKey = hotelCallBack.getSessionKey();
            String appKey = hotelCallBack.getAppKey();
            String secret = hotelCallBack.getSecret();
            String result = FZUtil.hotelUpdate(htHotelinfo, appKey, sessionKey, secret);
            if (!result.contains("xhotel_update_response")) {
                OpTaskDetail opTaskDetail = new OpTaskDetail();
                opTaskDetail.setHotelId(hotelId);
                opTaskDetail.setReason("酒店状态更改失败（上下架删除）" + "&" + result);
                opTaskDetailService.insertIgnoreNull(opTaskDetail);
            }
        }
    }
}
